#include "ServerConfigDialog.h"
#include "VirtualDeviceConfigDialog.h"
#include "utils/CsvHelper.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>
#include <QGroupBox>
#include <QLabel>
#include <QMessageBox>
#include <QHeaderView>
#include <QDialogButtonBox>
#include <QJsonArray>
#include <QFileDialog>
#include <QMap>

namespace ModbusPlexLink {

ServerConfigDialog::ServerConfigDialog(const QJsonObject& config, QWidget *parent)
    : QDialog(parent)
    , m_initialConfig(config)
    , m_isNewServer(config.isEmpty())
{
    setupUi();
    loadConfig();
    
    resize(700, 600);
}

ServerConfigDialog::~ServerConfigDialog() {
}

void ServerConfigDialog::setupUi() {
    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    
    // 基本信息部分
    QWidget* basicInfoWidget = createBasicInfoSection();
    mainLayout->addWidget(basicInfoWidget);
    
    // 虚拟设备表格部分
    QWidget* virtualDeviceWidget = createVirtualDeviceTableSection();
    mainLayout->addWidget(virtualDeviceWidget, 1);
    
    // 对话框按钮
    QDialogButtonBox* buttonBox = new QDialogButtonBox(
        QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
    
    connect(buttonBox, &QDialogButtonBox::accepted, this, &ServerConfigDialog::onAccepted);
    connect(buttonBox, &QDialogButtonBox::rejected, this, &ServerConfigDialog::onRejected);
    
    mainLayout->addWidget(buttonBox);
    
    setLayout(mainLayout);
}

QWidget* ServerConfigDialog::createBasicInfoSection() {
    QGroupBox* groupBox = new QGroupBox(tr("基本信息"), this);
    QFormLayout* formLayout = new QFormLayout(groupBox);
    
    // 服务器名称
    m_nameEdit = new QLineEdit(groupBox);
    m_nameEdit->setPlaceholderText(tr("例如：电表服务器1"));
    formLayout->addRow(tr("服务器名称:"), m_nameEdit);
    
    // 监听IP
    m_listenIpEdit = new QLineEdit(groupBox);
    m_listenIpEdit->setPlaceholderText(tr("0.0.0.0 表示监听所有网卡"));
    m_listenIpEdit->setText("0.0.0.0");
    formLayout->addRow(tr("监听IP:"), m_listenIpEdit);
    
    // 监听端口
    m_listenPortSpin = new QSpinBox(groupBox);
    m_listenPortSpin->setRange(1, 65535);
    m_listenPortSpin->setValue(502);
    formLayout->addRow(tr("监听端口:"), m_listenPortSpin);
    
    // 启用/禁用
    m_enabledCheck = new QCheckBox(tr("启用此服务器"), groupBox);
    m_enabledCheck->setChecked(true);
    formLayout->addRow("", m_enabledCheck);
    
    groupBox->setLayout(formLayout);
    return groupBox;
}

QWidget* ServerConfigDialog::createVirtualDeviceTableSection() {
    QGroupBox* groupBox = new QGroupBox(tr("虚拟设备列表"), this);
    QVBoxLayout* layout = new QVBoxLayout(groupBox);
    
    // 虚拟设备表格
    m_virtualDeviceTable = new QTableWidget(groupBox);
    m_virtualDeviceTable->setColumnCount(4);
    m_virtualDeviceTable->setHorizontalHeaderLabels({
        tr("虚拟从站ID"), tr("设备名称"), tr("映射数量"), tr("启用")
    });
    
    m_virtualDeviceTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_virtualDeviceTable->setSelectionMode(QAbstractItemView::SingleSelection);
    m_virtualDeviceTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_virtualDeviceTable->setAlternatingRowColors(true);
    m_virtualDeviceTable->horizontalHeader()->setStretchLastSection(true);
    m_virtualDeviceTable->verticalHeader()->setVisible(false);
    
    m_virtualDeviceTable->setColumnWidth(0, 100);
    m_virtualDeviceTable->setColumnWidth(1, 200);
    m_virtualDeviceTable->setColumnWidth(2, 100);
    m_virtualDeviceTable->setColumnWidth(3, 80);
    
    connect(m_virtualDeviceTable, &QTableWidget::itemSelectionChanged,
            this, &ServerConfigDialog::onVirtualDeviceTableSelectionChanged);
    connect(m_virtualDeviceTable, &QTableWidget::cellDoubleClicked,
            this, &ServerConfigDialog::onVirtualDeviceTableCellDoubleClicked);
    
    layout->addWidget(m_virtualDeviceTable);
    
    // 操作按钮
    QHBoxLayout* buttonLayout = new QHBoxLayout();
    
    m_addVirtualDeviceBtn = new QPushButton(tr("添加设备"), groupBox);
    m_editVirtualDeviceBtn = new QPushButton(tr("编辑设备"), groupBox);
    m_deleteVirtualDeviceBtn = new QPushButton(tr("删除设备"), groupBox);
    m_duplicateVirtualDeviceBtn = new QPushButton(tr("复制设备"), groupBox);
    m_batchImportBtn = new QPushButton(tr("批量导入"), groupBox);
    m_batchExportBtn = new QPushButton(tr("批量导出"), groupBox);
    
    m_editVirtualDeviceBtn->setEnabled(false);
    m_deleteVirtualDeviceBtn->setEnabled(false);
    m_duplicateVirtualDeviceBtn->setEnabled(false);
    
    // 设置批量按钮样式（突出显示）
    m_batchImportBtn->setStyleSheet("QPushButton { font-weight: bold; color: #0066CC; }");
    m_batchExportBtn->setEnabled(false);  // 初始禁用，有设备时启用
    
    connect(m_addVirtualDeviceBtn, &QPushButton::clicked,
            this, &ServerConfigDialog::onAddVirtualDevice);
    connect(m_editVirtualDeviceBtn, &QPushButton::clicked,
            this, &ServerConfigDialog::onEditVirtualDevice);
    connect(m_deleteVirtualDeviceBtn, &QPushButton::clicked,
            this, &ServerConfigDialog::onDeleteVirtualDevice);
    connect(m_duplicateVirtualDeviceBtn, &QPushButton::clicked,
            this, &ServerConfigDialog::onDuplicateVirtualDevice);
    connect(m_batchImportBtn, &QPushButton::clicked,
            this, &ServerConfigDialog::onBatchImportVirtualDevices);
    connect(m_batchExportBtn, &QPushButton::clicked,
            this, &ServerConfigDialog::onBatchExportVirtualDevices);
    
    buttonLayout->addWidget(m_addVirtualDeviceBtn);
    buttonLayout->addWidget(m_editVirtualDeviceBtn);
    buttonLayout->addWidget(m_deleteVirtualDeviceBtn);
    buttonLayout->addWidget(m_duplicateVirtualDeviceBtn);
    buttonLayout->addStretch();
    buttonLayout->addWidget(m_batchImportBtn);
    buttonLayout->addWidget(m_batchExportBtn);
    
    layout->addLayout(buttonLayout);
    
    groupBox->setLayout(layout);
    return groupBox;
}

void ServerConfigDialog::loadConfig() {
    if (m_initialConfig.isEmpty()) {
        return;
    }
    
    // 加载基本信息
    m_nameEdit->setText(m_initialConfig.value("name").toString());
    
    // 兼容旧字段名 (listenIp) 和新字段名 (listenAddress)
    QString listenAddress = m_initialConfig.value("listenAddress").toString();
    if (listenAddress.isEmpty()) {
        listenAddress = m_initialConfig.value("listenIp").toString("0.0.0.0");
    }
    m_listenIpEdit->setText(listenAddress);
    
    // 兼容旧字段名 (listenPort) 和新字段名 (port)
    int port = m_initialConfig.value("port").toInt(0);
    if (port == 0) {
        port = m_initialConfig.value("listenPort").toInt(502);
    }
    m_listenPortSpin->setValue(port);
    
    m_enabledCheck->setChecked(m_initialConfig.value("enabled").toBool(true));
    
    // 加载虚拟设备列表
    QJsonArray virtualDevicesArray = m_initialConfig.value("virtualDevices").toArray();
    for (const QJsonValue& value : virtualDevicesArray) {
        if (value.isObject()) {
            m_virtualDevices.append(value.toObject());
        }
    }
    
    refreshVirtualDeviceTable();
}

bool ServerConfigDialog::validateConfig() {
    // 验证服务器名称
    if (m_nameEdit->text().trimmed().isEmpty()) {
        QMessageBox::warning(this, tr("验证失败"), tr("请输入服务器名称"));
        m_nameEdit->setFocus();
        return false;
    }
    
    // 验证监听IP
    if (m_listenIpEdit->text().trimmed().isEmpty()) {
        QMessageBox::warning(this, tr("验证失败"), tr("请输入监听IP地址"));
        m_listenIpEdit->setFocus();
        return false;
    }
    
    // 验证虚拟设备列表
    if (m_virtualDevices.isEmpty()) {
        QMessageBox::warning(this, tr("验证失败"), 
            tr("至少需要添加一个虚拟设备\n\n提示：点击\"添加设备\"按钮创建虚拟设备"));
        return false;
    }
    
    // 检查虚拟从站ID是否重复
    QSet<int> unitIds;
    for (const QJsonObject& vd : m_virtualDevices) {
        int unitId = vd.value("virtualUnitId").toInt();
        if (unitIds.contains(unitId)) {
            QMessageBox::warning(this, tr("验证失败"), 
                tr("虚拟从站ID %1 重复，请确保每个虚拟设备的从站ID唯一").arg(unitId));
            return false;
        }
        unitIds.insert(unitId);
    }
    
    return true;
}

QJsonObject ServerConfigDialog::getConfig() const {
    QJsonObject config;
    config["protocol"] = "modbus-tcp";  // 添加协议类型
    config["name"] = m_nameEdit->text().trimmed();
    config["listenAddress"] = m_listenIpEdit->text().trimmed();  // 使用标准字段名
    config["port"] = m_listenPortSpin->value();                   // 使用标准字段名
    config["enabled"] = m_enabledCheck->isChecked();
    
    // ModbusTcpServer 需要的其他字段（使用默认值）
    config["timeout"] = 1000;
    config["maxClients"] = 10;
    config["logRequests"] = false;
    config["logErrors"] = true;
    
    QJsonArray virtualDevicesArray;
    for (const QJsonObject& vd : m_virtualDevices) {
        virtualDevicesArray.append(vd);
    }
    config["virtualDevices"] = virtualDevicesArray;
    
    return config;
}

void ServerConfigDialog::refreshVirtualDeviceTable() {
    m_virtualDeviceTable->setRowCount(m_virtualDevices.size());
    
    for (int i = 0; i < m_virtualDevices.size(); ++i) {
        const QJsonObject& vd = m_virtualDevices[i];
        
        // 虚拟从站ID
        QTableWidgetItem* unitIdItem = new QTableWidgetItem(
            QString::number(vd.value("virtualUnitId").toInt()));
        unitIdItem->setTextAlignment(Qt::AlignCenter);
        m_virtualDeviceTable->setItem(i, 0, unitIdItem);
        
        // 设备名称
        QTableWidgetItem* nameItem = new QTableWidgetItem(
            vd.value("name").toString());
        m_virtualDeviceTable->setItem(i, 1, nameItem);
        
        // 映射数量
        int mappingCount = vd.value("mappings").toArray().size();
        QTableWidgetItem* mappingItem = new QTableWidgetItem(
            QString::number(mappingCount));
        mappingItem->setTextAlignment(Qt::AlignCenter);
        m_virtualDeviceTable->setItem(i, 2, mappingItem);
        
        // 启用状态
        QTableWidgetItem* enabledItem = new QTableWidgetItem(
            vd.value("enabled").toBool(true) ? tr("是") : tr("否"));
        enabledItem->setTextAlignment(Qt::AlignCenter);
        m_virtualDeviceTable->setItem(i, 3, enabledItem);
    }
    
    updateVirtualDeviceButtons();
}

void ServerConfigDialog::updateVirtualDeviceButtons() {
    bool hasSelection = m_virtualDeviceTable->currentRow() >= 0;
    bool hasDevices = !m_virtualDevices.isEmpty();
    
    m_editVirtualDeviceBtn->setEnabled(hasSelection);
    m_deleteVirtualDeviceBtn->setEnabled(hasSelection);
    m_duplicateVirtualDeviceBtn->setEnabled(hasSelection);
    m_batchExportBtn->setEnabled(hasDevices);  // 有设备时启用批量导出
}

void ServerConfigDialog::onAddVirtualDevice() {
    VirtualDeviceConfigDialog dialog(QJsonObject(), this);
    dialog.setWindowTitle(tr("新建虚拟设备"));

    if (dialog.exec() == QDialog::Accepted) {
        QJsonObject config = dialog.getConfig();
        m_virtualDevices.append(config);
        refreshVirtualDeviceTable();
        m_virtualDeviceTable->selectRow(m_virtualDevices.size() - 1);
    }
}

void ServerConfigDialog::onEditVirtualDevice() {
    int row = m_virtualDeviceTable->currentRow();
    if (row < 0 || row >= m_virtualDevices.size()) {
        return;
    }

    VirtualDeviceConfigDialog dialog(m_virtualDevices[row], this);
    dialog.setWindowTitle(tr("编辑虚拟设备 - %1")
        .arg(m_virtualDevices[row].value("name").toString()));

    if (dialog.exec() == QDialog::Accepted) {
        QJsonObject config = dialog.getConfig();
        m_virtualDevices[row] = config;
        refreshVirtualDeviceTable();
    }
}

void ServerConfigDialog::onDeleteVirtualDevice() {
    int row = m_virtualDeviceTable->currentRow();
    if (row < 0 || row >= m_virtualDevices.size()) {
        return;
    }
    
    QString deviceName = m_virtualDevices[row].value("name").toString();
    QMessageBox::StandardButton reply = QMessageBox::question(
        this, tr("确认删除"), 
        tr("确定要删除虚拟设备 '%1' 吗？").arg(deviceName),
        QMessageBox::Yes | QMessageBox::No);
    
    if (reply == QMessageBox::Yes) {
        m_virtualDevices.removeAt(row);
        refreshVirtualDeviceTable();
    }
}

void ServerConfigDialog::onDuplicateVirtualDevice() {
    int row = m_virtualDeviceTable->currentRow();
    if (row < 0 || row >= m_virtualDevices.size()) {
        return;
    }
    
    // 复制选中的虚拟设备
    QJsonObject vd = m_virtualDevices[row];
    
    // 智能递增虚拟从站ID
    int maxUnitId = 0;
    for (const QJsonObject& device : m_virtualDevices) {
        maxUnitId = qMax(maxUnitId, device.value("virtualUnitId").toInt());
    }
    vd["virtualUnitId"] = maxUnitId + 1;
    
    // 修改名称
    QString originalName = vd.value("name").toString();
    vd["name"] = originalName + tr("_副本");
    
    m_virtualDevices.append(vd);
    refreshVirtualDeviceTable();
    m_virtualDeviceTable->selectRow(m_virtualDevices.size() - 1);
}

void ServerConfigDialog::onVirtualDeviceTableSelectionChanged() {
    updateVirtualDeviceButtons();
}

void ServerConfigDialog::onVirtualDeviceTableCellDoubleClicked(int row, int column) {
    Q_UNUSED(column);
    if (row >= 0 && row < m_virtualDevices.size()) {
        onEditVirtualDevice();
    }
}

void ServerConfigDialog::onAccepted() {
    if (validateConfig()) {
        accept();
    }
}

void ServerConfigDialog::onRejected() {
    reject();
}

void ServerConfigDialog::onBatchImportVirtualDevices() {
    QString fileName = QFileDialog::getOpenFileName(
        this,
        tr("批量导入虚拟设备"),
        "",
        tr("CSV文件 (*.csv)")
    );
    
    if (fileName.isEmpty()) {
        return;
    }
    
    // 导入CSV
    QMap<int, QList<ServerMappingRule>> devicesMap;
    QString errorMsg;
    
    if (!CsvHelper::importBatchVirtualDevices(fileName, devicesMap, errorMsg)) {
        QMessageBox::critical(this, tr("导入失败"), 
            tr("无法导入CSV文件：\n%1").arg(errorMsg));
        return;
    }
    
    // 询问是否清空现有设备
    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        tr("导入模式"),
        tr("成功解析 %1 个虚拟设备，共 %2 条映射规则。\n\n"
           "是否清空现有虚拟设备？\n\n"
           "点击【是】：清空现有设备，只保留导入的\n"
           "点击【否】：追加导入的设备到现有列表")
            .arg(devicesMap.size())
            .arg([&devicesMap](){
                int total = 0;
                for (const auto& mappings : devicesMap) {
                    total += mappings.size();
                }
                return total;
            }()),
        QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel
    );
    
    if (reply == QMessageBox::Cancel) {
        return;
    }
    
    if (reply == QMessageBox::Yes) {
        m_virtualDevices.clear();
    }
    
    // 创建虚拟设备
    QList<int> unitIds = devicesMap.keys();
    std::sort(unitIds.begin(), unitIds.end());
    
    for (int unitId : unitIds) {
        QJsonObject vd;
        vd["virtualUnitId"] = unitId;
        vd["name"] = QString("虚拟设备%1").arg(unitId);
        vd["enabled"] = true;
        
        // 转换映射规则
        QJsonArray mappingsArray;
        for (const ServerMappingRule& rule : devicesMap[unitId]) {
            QJsonObject mapping;
            mapping["tagName"] = rule.tagName;
            mapping["comment"] = rule.comment;
            mapping["registerType"] = DataTypeUtils::registerTypeToString(rule.registerType);
            mapping["address"] = rule.address;
            mapping["dataType"] = DataTypeUtils::dataTypeToString(rule.dataType);
            mapping["byteOrder"] = DataTypeUtils::byteOrderToString(rule.byteOrder);
            mapping["scale"] = rule.scale;
            mapping["offset"] = rule.offset;
            mapping["writable"] = rule.writable;
            
            mappingsArray.append(mapping);
        }
        
        vd["mappings"] = mappingsArray;
        m_virtualDevices.append(vd);
    }
    
    // 刷新表格
    refreshVirtualDeviceTable();
    
    QMessageBox::information(this, tr("导入成功"), 
        tr("成功导入 %1 个虚拟设备！").arg(devicesMap.size()));
}

void ServerConfigDialog::onBatchExportVirtualDevices() {
    if (m_virtualDevices.isEmpty()) {
        QMessageBox::information(this, tr("提示"), 
            tr("当前没有虚拟设备可导出。"));
        return;
    }
    
    QString fileName = QFileDialog::getSaveFileName(
        this,
        tr("批量导出虚拟设备"),
        QString("batch_virtual_devices_%1.csv").arg(m_nameEdit->text()),
        tr("CSV文件 (*.csv)")
    );
    
    if (fileName.isEmpty()) {
        return;
    }
    
    // 收集所有虚拟设备的映射
    QMap<int, QList<ServerMappingRule>> devicesMap;
    
    for (const QJsonObject& vd : m_virtualDevices) {
        int unitId = vd.value("virtualUnitId").toInt();
        QJsonArray mappingsArray = vd.value("mappings").toArray();
        
        QList<ServerMappingRule> mappings;
        for (const QJsonValue& val : mappingsArray) {
            QJsonObject mapping = val.toObject();
            
            ServerMappingRule rule;
            rule.tagName = mapping.value("tagName").toString();
            rule.comment = mapping.value("comment").toString();
            rule.registerType = DataTypeUtils::registerTypeFromString(
                mapping.value("registerType").toString());
            rule.address = mapping.value("address").toInt();
            rule.dataType = DataTypeUtils::dataTypeFromString(
                mapping.value("dataType").toString());
            rule.byteOrder = DataTypeUtils::byteOrderFromString(
                mapping.value("byteOrder").toString());
            rule.scale = mapping.value("scale").toDouble(1.0);
            rule.offset = mapping.value("offset").toDouble(0.0);
            rule.writable = mapping.value("writable").toBool(false);
            
            mappings.append(rule);
        }
        
        devicesMap[unitId] = mappings;
    }
    
    // 导出
    if (CsvHelper::exportBatchVirtualDevices(devicesMap, fileName)) {
        int totalMappings = 0;
        for (const auto& mappings : devicesMap) {
            totalMappings += mappings.size();
        }
        QMessageBox::information(this, tr("导出成功"), 
            tr("成功导出 %1 个虚拟设备，共 %2 条映射规则到：\n%3")
                .arg(devicesMap.size())
                .arg(totalMappings)
                .arg(fileName));
    } else {
        QMessageBox::critical(this, tr("导出失败"), 
            tr("无法导出CSV文件。"));
    }
}

} // namespace ModbusPlexLink

